package cn.example.demo.modules.house.service.impl;

import cn.example.demo.common.db.pojo.entity.BaseEntity;
import cn.example.demo.common.model.service.ServiceResult;
import cn.example.demo.common.retrieval.PageBean;
import cn.example.demo.common.secure.annotation.DataScopeEnable;
import cn.example.demo.common.secure.context.LoginUserApi;
import cn.example.demo.common.secure.dto.LoginUser;
import cn.example.demo.common.tools.QueryServiceUtils;
import cn.example.demo.common.tools.obj.DateAgeUtils;
import cn.example.demo.common.tools.obj.reflect.EntityUtils;
import cn.example.demo.modules.house.dict.AppraiseScore;
import cn.example.demo.modules.house.dto.HousingOrderDto;
import cn.example.demo.modules.house.entity.House;
import cn.example.demo.modules.house.entity.HousingOrder;
import cn.example.demo.modules.house.entity.Meals;
import cn.example.demo.modules.house.entity.SysConfig;
import cn.example.demo.modules.house.mapper.HouseMapper;
import cn.example.demo.modules.house.mapper.HousingOrderMapper;
import cn.example.demo.modules.house.mapper.SysConfigMapper;
import cn.example.demo.modules.house.service.IHousingOrderService;
import cn.example.demo.modules.house.service.IMealsService;
import cn.example.demo.modules.sys.model.entity.SysUser;
import cn.example.demo.modules.sys.service.UserService;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.mail.MailAccount;
import cn.hutool.extra.mail.MailUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 描述：【租房订单】接口实现类
 */
@Slf4j
@EnableAspectJAutoProxy(exposeProxy = true, proxyTargetClass = true)
@Service
public class HousingOrderServiceImpl extends ServiceImpl<HousingOrderMapper, HousingOrder> implements IHousingOrderService {
    @Autowired
    private LoginUserApi loginUserApi;
    @Resource
    private HouseMapper houseMapper;
    @Resource
    private IMealsService mealsService;
    @Resource
    private UserService userService;
    @Resource
    private SysConfigMapper sysConfigMapper;
    @Autowired
    private TemplateEngine templateEngine;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public ServiceResult insertHousingOrder(HousingOrderDto housingOrderDto) {
        // 1.查询房源信息
        House house = houseMapper.selectById(housingOrderDto.getHouseId());

        // 封装数据
        if (house != null) {
            if (house.getInventory() < house.getOrdering() + 1) {
                return ServiceResult.isNotModified("库存不足！");
            }

            HousingOrder entity = EntityUtils.entityConvert(housingOrderDto, new HousingOrder(), false);
            // 入住天数计算
            BigDecimal b1 = BigDecimal.valueOf(entity.getOrderEndTime().getTime() - entity.getOrderStartTime().getTime());
            BigDecimal days = b1.divide(BigDecimal.valueOf(3600 * 1000 * 24), RoundingMode.CEILING);

            // 默认状态（待付款）
            entity.setOrderStatus(1);
            entity.setHouseOwner(house.getCreateUser());
            entity.setHousingDay(days.intValue());
            // 房费计算：单价 * 天数 * 折扣价
            entity.setHouseCost(house.getCost().multiply(days).multiply(house.getDiscount()));

            // 餐饮不为空
            if (StrUtil.isNotBlank(housingOrderDto.getMealId())) {
                // 查询餐饮信息
                Meals meals = mealsService.findMealsById(housingOrderDto.getMealId());
                // 餐饮费计算：单价 * 天数
                entity.setMealCost(meals.getPrice().multiply(days));
                // 总费：房费 + 餐饮
                entity.setTotalCost(entity.getHouseCost().add(entity.getMealCost()));
            } else {
                // 总费：房费
                entity.setTotalCost(entity.getHouseCost());
            }

            // TODO-lzx 预付定金暂时从 totalCost 字段获取
            entity.setPrePay(entity.getTotalCost());

            if (this.save(entity)) {
                // 房源库存更新
                house.setOrdering(house.getOrdering() + 1);
                houseMapper.updateById(house);

                return ServiceResult.isSuccess(StrUtil.format("【租房订单，ID:{}】创建成功!", entity.getId()), entity);
            }
        }

        return ServiceResult.isInternalError("【租房订单】创建失败，未知错误！");
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public ServiceResult updateHousingOrder(HousingOrderDto housingOrderDto) {
        HousingOrder entity = this.getById(housingOrderDto.getId());
        if (entity == null) {
            return ServiceResult.isNotFound(StrUtil.format("【租房订单】信息更新失败：记录不存在！ID:{}", housingOrderDto.getId()));
        }

        entity = EntityUtils.entityConvert(housingOrderDto, entity, true);
        if (this.updateById(entity)) {
            return ServiceResult.isSuccess(StrUtil.format("【租房订单，ID:{}】信息更新成功!", entity.getId()), null);
        }

        return ServiceResult.isNotModified("未知错误，【租房订单】信息修改失败！");
    }

    @Override
    public PageBean queryHousingOrder(HousingOrderDto housingOrderDto) {
        // 当前实现类代理对象
        HousingOrderServiceImpl proxy = (HousingOrderServiceImpl) AopContext.currentProxy();

        Page pageResult = PageHelper.startPage(housingOrderDto.getPageNum(), housingOrderDto.getPageSize())
                .doSelectPage(() -> this.list(proxy.getQueryWrapper(housingOrderDto)));

        return QueryServiceUtils.encapsulatePageBean(new PageBean<>(), pageResult);
    }

    @Override
    public PageBean queryOwnedHousingOrder(HousingOrderDto housingOrderDto) {
        // 当前实现类代理对象
        HousingOrderServiceImpl proxy = (HousingOrderServiceImpl) AopContext.currentProxy();

        Page pageResult = PageHelper.startPage(housingOrderDto.getPageNum(), housingOrderDto.getPageSize())
                .doSelectPage(() -> this.list(proxy.getQueryWrapper2(housingOrderDto)));

        return QueryServiceUtils.encapsulatePageBean(new PageBean<>(), pageResult);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public ServiceResult deleteHousingOrder(HousingOrderDto housingOrderDto) {
        int rows = this.baseMapper.deleteBatchIds(housingOrderDto.getIds());
        if (rows > 0) {
            return ServiceResult.isSuccess(StrUtil.format("操作成功，已批量删除【租房订单】共 {} 条记录！", rows), rows);
        }

        return ServiceResult.isNotModified("删除【租房订单】失败，请稍后重试！");
    }

    @Override
    public HousingOrder findHousingOrderById(String id) {
        return this.getById(id);
    }

    @Override
    public List<Map<String, Object>> queryHousingOrderAsDict(HousingOrderDto housingOrderDto) {
        return this.baseMapper.selectAsDictList(getQueryWrapper(housingOrderDto));
    }

    @Override
    public ServiceResult batchUpdateStatus(HousingOrderDto houseDto) {
        LambdaUpdateWrapper<HousingOrder> wrapper = Wrappers.lambdaUpdate();
        wrapper.set(HousingOrder::getOrderStatus, houseDto.getOrderStatus())
                .in(HousingOrder::getId, houseDto.getIds());

        if (this.update(wrapper)) {
            return ServiceResult.isSuccess(StrUtil.format("操作成功，已批量修改【订单状态】，共 {} 条记录！", houseDto.getIds().size()), houseDto.getIds().size());
        }

        return ServiceResult.isNotModified("批量修改【订单状态】失败，请稍后重试！");
    }

    @Override
    public PageBean queryHousingOrderWithUserInfo(HousingOrderDto housingOrderDto) {
        QueryWrapper<HousingOrder> wrapper = Wrappers.query();

        wrapper.eq(housingOrderDto.getHouseId() != null, "t1.house_id", housingOrderDto.getHouseId())
                .eq(housingOrderDto.getOrderStatus() != null, "t1.order_status", housingOrderDto.getOrderStatus())
                .orderByDesc("t1.update_time");

        Page pageResult = PageHelper.startPage(housingOrderDto.getPageNum(), housingOrderDto.getPageSize())
                .doSelectPage(() -> this.baseMapper.selectJoinSysUser(wrapper));

        return QueryServiceUtils.encapsulatePageBean(new PageBean<>(), pageResult);
    }

    @Override
    public ServiceResult dataStatistic() {
        LoginUser loginUser = loginUserApi.getCurrentLoginUser();
        // 条件查询
        LambdaQueryWrapper<HousingOrder> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(HousingOrder::getHouseOwner, loginUser.getUserId())  // 房东本人
                .ne(HousingOrder::getOrderStatus, 1)  // 已支付的订单
                .orderByAsc(HousingOrder::getCreateTime);

        List<HousingOrder> orderList = this.list(wrapper);

        if (ObjectUtil.isEmpty(orderList)) {
            return ServiceResult.isNotFound("未查询到统计数据！");
        }

        // 统计指标：
        // 1）月度销售总额
        Map<String, BigDecimal> count1 = orderList.stream().collect(Collectors.groupingBy(o ->
                        DateAgeUtils.dateToString(o.getCreateTime(), "yyyy-MM"), TreeMap::new,
                Collectors.mapping(HousingOrder::getTotalCost, Collectors.reducing(BigDecimal.ZERO.stripTrailingZeros(), (o1, o2) -> o1.add(o2)))));

        // 2）评分-单量统计
        List<Map> appraiseCount = new ArrayList<>();
        orderList.stream()
                .filter(o -> o.getStarMark() != null)
                .collect(Collectors.groupingBy(HousingOrder::getStarMark, Collectors.counting()))
                .entrySet()
                .forEach(o -> {
                    Map<String, Object> m = new HashMap<>();
                    m.put("name", AppraiseScore.codeToName(o.getKey().toString()));
                    m.put("value", o.getValue());
                    appraiseCount.add(m);
                });

        // 2）评分-单量统计
        List<Map> houseCount = new ArrayList<>();
        orderList.stream()
                .collect(Collectors.groupingBy(HousingOrder::getHouseId,
                        Collectors.mapping(HousingOrder::getTotalCost, Collectors.reducing(BigDecimal.ZERO.stripTrailingZeros(), (o1, o2) -> o1.add(o2)))))
                .entrySet()
                .forEach(o -> {
                    Map<String, Object> m = new HashMap<>();
                    m.put("name", o.getKey());
                    m.put("value", o.getValue());
                    houseCount.add(m);
                });

        // 返回数据结构体
        Map<String, Object> map = new HashMap<>();

        // 月度销售指标
        map.put("timeX", count1.keySet());
        map.put("costY", count1.values());
        // 分类统计指标1
        map.put("appraiseCount", appraiseCount);
        // 分类统计指标1
        map.put("houseCount", houseCount);
        System.out.println("------------------- 执行咯-------------------");
        System.out.println(map);
        return ServiceResult.isSuccess(map);
    }

    @Scheduled(cron = "${global.schedule.cron}")
    @Override
    public void refreshOrderStatus() {
        // 查询日期参数
        Date date = new Date();
        Date date1 = DateAgeUtils.addDayAmountOfDate(date, 1);
        Date date2 = DateAgeUtils.addDayAmountOfDate(date, -1);
        LambdaQueryWrapper<HousingOrder> queryWrapper = Wrappers.lambdaQuery();
        // 1.查询当天即将入住的订单
        queryWrapper.gt(HousingOrder::getOrderStartTime, date)
                .lt(HousingOrder::getOrderStartTime, date1);
        List<HousingOrder> list = this.list(queryWrapper);
        // 1.查询当天已离店的订单
        queryWrapper.clear();
        queryWrapper.gt(HousingOrder::getOrderEndTime, date2)
                .lt(HousingOrder::getOrderEndTime, date);
        // TODO-lzx 待优化。遍历执行订单结算
        this.list(queryWrapper).forEach(o -> {
            HousingOrderDto dto = new HousingOrderDto();
            dto.setId(o.getId());
            this.finishHousing(dto);
        });
        // 修改状态
        list.forEach(o -> o.setOrderStatus(4)); // 入住中
        // 更新订单状态
//        list.addAll(list2);
        if (!list.isEmpty()) {
            this.updateBatchById(list);
        }
        log.info("^_^^_^^_^^_^ 订单状态定时任务执行啦！ ^_^^_^^_^^_^");
    }

    @Override
    public void mailAdvice(String orderId) {
        // TODO-lzx 从缓存获取系统参数
        List<SysConfig> configs = sysConfigMapper.selectList(null);
        Map<String, String> configMap = configs.stream().collect(Collectors.toMap(SysConfig::getParamKey, SysConfig::getParamValue));

        HousingOrder entity = this.getById(orderId);
        if (entity != null) {
            // 数据获取
            House house = houseMapper.selectById(entity.getHouseId());
            SysUser user = userService.findUserByUserId(entity.getHouseOwner());

            // 邮件正文生成（Thymeleaf 模板引擎）
            Map<String, Object> map = new HashMap<>();
            Context context = new Context();

            context.setVariable("entity", entity);
            context.setVariable("houseTitle", house.getHouseTitle());
            context.setVariable("realName", user.getRealName());

            String htmlString = templateEngine.process("house/orderDetail", context);

            // 邮件发送人
            MailAccount mailAccount = new MailAccount();
            mailAccount.setHost("smtp.qq.com");
            mailAccount.setPort(465);
            mailAccount.setSslEnable(true);
            mailAccount.setFrom(configMap.get("qq.mail.username"));
            mailAccount.setUser(configMap.get("qq.mail.username"));
            mailAccount.setPass(configMap.get("qq.mail.password"));

            // 邮件发送
            MailUtil.send(mailAccount, user.getEmail(), "民宿住房平台交易提醒", htmlString, true);
        }
    }

    @Override
    public ServiceResult continueHousing(HousingOrderDto housingOrderDto) {
        // 1.查找订单
        HousingOrder housingOrder = this.getById(housingOrderDto.getId());
        // 2.查找房源信息
        House house = houseMapper.selectById(housingOrder.getHouseId());
        if (house == null) {
            return ServiceResult.isNotFound(StrUtil.format("房源已不存在，该订单{}无法做任何编辑！"));
        }

        // 封装数据
        if (housingOrder != null) {
            // 重新计算入住天数
            BigDecimal b1 = BigDecimal.valueOf(housingOrderDto.getOrderEndTime().getTime() - housingOrder.getOrderStartTime().getTime());
            BigDecimal days = b1.divide(BigDecimal.valueOf(3600 * 1000 * 24), RoundingMode.CEILING);

            // 住房天数
            housingOrder.setHousingDay(days.intValue());
            housingOrder.setOrderEndTime(housingOrderDto.getOrderEndTime());
            // 房费计算：单价 * 天数
            housingOrder.setHouseCost(house.getCost().multiply(days));

            // 餐饮不为空
            if (StrUtil.isNotBlank(housingOrder.getMealId())) {
                // 查询餐饮信息
                Meals meals = mealsService.findMealsById(housingOrder.getMealId());
                // 餐饮费计算：单价 * 天数
                housingOrder.setMealCost(meals.getPrice().multiply(days));
                // 总费：房费 + 餐饮
                housingOrder.setTotalCost(housingOrder.getHouseCost().add(housingOrder.getMealCost()));
            } else {
                // 总费：房费
                housingOrder.setTotalCost(housingOrder.getHouseCost());
            }

            if (this.updateById(housingOrder)) {
                return ServiceResult.isSuccess(StrUtil.format("【租房订单，ID:{}】更新成功!", housingOrder.getId()), housingOrder);
            }
        }

        return ServiceResult.isInternalError("【租房订单】更新失败，未知错误！");
    }

    @Override
    public ServiceResult finishHousing(HousingOrderDto housingOrderDto) {
        // 1.查找订单
        HousingOrder housingOrder = this.getById(housingOrderDto.getId());
        // 2.查找房源信息
        House house = houseMapper.selectById(housingOrder.getHouseId());
        if (house == null) {
            return ServiceResult.isNotFound(StrUtil.format("房源已不存在，该订单{}无法做任何编辑！"));
        }
        // 封装数据
        if (housingOrder != null) {
            // 退房其他补充说明：物品损坏，床品更换、卫生打扫等
            housingOrder = EntityUtils.entityConvert(housingOrderDto, housingOrder, true);
            housingOrder.setLeaveHouseDate(new Date());
            // TODO-lzx 实际情况应该以最新日期为主，为模拟效果，这里用未来定好的退房日期
//            Date endDate = new Date();
            Date endDate = housingOrder.getOrderEndTime();
            // 重新计算入住天数
            BigDecimal b1 = BigDecimal.valueOf(endDate.getTime() - housingOrder.getOrderStartTime().getTime());
            BigDecimal days = b1.divide(BigDecimal.valueOf(3600 * 1000 * 24), RoundingMode.CEILING);
            // 状态改为待评价
            housingOrder.setOrderStatus(5);
            // 住房天数
            housingOrder.setHousingDay(days.intValue());
            housingOrder.setOrderEndTime(endDate);
            // 房费计算：单价 * 天数
            housingOrder.setHouseCost(house.getCost().multiply(days));
            // 餐饮不为空
            if (StrUtil.isNotBlank(housingOrder.getMealId())) {
                // 查询餐饮信息
                Meals meals = mealsService.findMealsById(housingOrder.getMealId());
                // 餐饮费计算：单价 * 天数
                housingOrder.setMealCost(meals.getPrice().multiply(days));
                // 总费：房费 + 餐饮
                housingOrder.setTotalCost(housingOrder.getHouseCost().add(housingOrder.getMealCost()));
            } else {
                // 总费：房费
                housingOrder.setTotalCost(housingOrder.getHouseCost());
            }
            // 差价计算（实际总费用 - 预付定金）
            BigDecimal diff = housingOrder.getTotalCost().subtract(housingOrder.getPrePay() == null ? BigDecimal.ZERO : housingOrder.getPrePay());
            if (diff.compareTo(BigDecimal.ZERO) > 0) {
                housingOrder.setAppendPay(diff);
                housingOrder.setReturnCost(BigDecimal.ZERO);
            } else {
                housingOrder.setAppendPay(BigDecimal.ZERO);
                housingOrder.setReturnCost(diff);
            }
            // 更新订单信息
            if (this.updateById(housingOrder)) {
                // 房源库存更新
                house.setOrdering(house.getOrdering() - 1);
                houseMapper.updateById(house);
                return ServiceResult.isSuccess(StrUtil.format("【租房订单，ID:{}】更新成功!", housingOrder.getId()), housingOrder);
            }
        }
        return ServiceResult.isInternalError("【租房订单】更新失败，未知错误！");
    }

    /**
     * 每10秒执行1次
     */
    @Scheduled(cron = "5/10 * * * * ?")
    @Override
    public void refreshOrderStatusIfOutOf24Hours() {
        LambdaQueryWrapper<HousingOrder> queryWrapper = Wrappers.lambdaQuery();
        // 1.查询状态为待支付的订单
        queryWrapper.eq(HousingOrder::getOrderStatus, 1);
        List<HousingOrder> list = this.list(queryWrapper);
        // 过滤超过24小时的订单
        List<String> orderIds = list.stream()
                .filter(o -> DateUtil.between(o.getCreateTime(), new Date(), DateUnit.HOUR) > 24l)
                .map(HousingOrder::getId)
                .collect(Collectors.toList());
        // 批量更新状态为取消订单
        if (ObjectUtil.isNotEmpty(orderIds)) {
            HousingOrderDto orderDto = new HousingOrderDto();
            orderDto.setIds(orderIds);
            orderDto.setOrderStatus(7);
            this.batchUpdateStatus(orderDto);
        }
    }

    /**
     * 查询条件（管理）
     *
     * @param housingOrderDto
     * @return
     */
    @DataScopeEnable(userIdField = "house_owner")
    protected LambdaQueryWrapper getQueryWrapper(HousingOrderDto housingOrderDto) {
        return commonQueryWrapper(housingOrderDto);
    }

    /**
     * 查询条件（个人）
     *
     * @param housingOrderDto
     * @return
     */
    @DataScopeEnable
    protected LambdaQueryWrapper getQueryWrapper2(HousingOrderDto housingOrderDto) {
        return commonQueryWrapper(housingOrderDto);
    }

    /**
     * 通用查询条件
     *
     * @param housingOrderDto
     * @return
     */
    private LambdaQueryWrapper commonQueryWrapper(HousingOrderDto housingOrderDto) {
        LambdaQueryWrapper<HousingOrder> wrapper = Wrappers.lambdaQuery();

        wrapper
                .eq(StrUtil.isNotBlank(housingOrderDto.getId()), HousingOrder::getId, housingOrderDto.getId())
                .like(StrUtil.isNotBlank(housingOrderDto.getHouseId()), HousingOrder::getHouseId, housingOrderDto.getHouseId())
                .eq(housingOrderDto.getHouseOwner() != null, HousingOrder::getHouseOwner, housingOrderDto.getHouseOwner())
                .like(StrUtil.isNotBlank(housingOrderDto.getMealId()), HousingOrder::getMealId, housingOrderDto.getMealId())
                .like(StrUtil.isNotBlank(housingOrderDto.getIsNeedMeal()), HousingOrder::getIsNeedMeal, housingOrderDto.getIsNeedMeal())
                .ge(housingOrderDto.getOrderStartTimeStart() != null, HousingOrder::getOrderStartTime, housingOrderDto.getOrderStartTimeStart())
                .le(housingOrderDto.getOrderStartTimeEnd() != null, HousingOrder::getOrderStartTime, housingOrderDto.getOrderStartTimeEnd())
                .ge(housingOrderDto.getOrderEndTimeStart() != null, HousingOrder::getOrderEndTime, housingOrderDto.getOrderEndTimeStart())
                .le(housingOrderDto.getOrderEndTimeEnd() != null, HousingOrder::getOrderEndTime, housingOrderDto.getOrderEndTimeEnd())
                .eq(housingOrderDto.getHouseCost() != null, HousingOrder::getHouseCost, housingOrderDto.getHouseCost())
                .eq(housingOrderDto.getStarMark() != null, HousingOrder::getStarMark, housingOrderDto.getStarMark())
                .like(StrUtil.isNotBlank(housingOrderDto.getAppraise()), HousingOrder::getAppraise, housingOrderDto.getAppraise())
                .like(StrUtil.isNotBlank(housingOrderDto.getReply()), HousingOrder::getReply, housingOrderDto.getReply())
                .eq(housingOrderDto.getOrderStatus() != null, HousingOrder::getOrderStatus, housingOrderDto.getOrderStatus())
                .eq(housingOrderDto.getOrganizationId() != null, HousingOrder::getOrganizationId, housingOrderDto.getOrganizationId())
                .eq(housingOrderDto.getCreateUser() != null, HousingOrder::getCreateUser, housingOrderDto.getCreateUser())
                .like(StrUtil.isNotBlank(housingOrderDto.getCreateUserName()), HousingOrder::getCreateUserName, housingOrderDto.getCreateUserName())
                .ge(housingOrderDto.getCreateTimeStart() != null, HousingOrder::getCreateTime, housingOrderDto.getCreateTimeStart())
                .le(housingOrderDto.getCreateTimeEnd() != null, HousingOrder::getCreateTime, housingOrderDto.getCreateTimeEnd())
                .eq(housingOrderDto.getUpdateUser() != null, HousingOrder::getUpdateUser, housingOrderDto.getUpdateUser())
                .like(StrUtil.isNotBlank(housingOrderDto.getUpdateUserName()), HousingOrder::getUpdateUserName, housingOrderDto.getUpdateUserName())
                .ge(housingOrderDto.getUpdateTimeStart() != null, HousingOrder::getUpdateTime, housingOrderDto.getUpdateTimeStart())
                .le(housingOrderDto.getUpdateTimeEnd() != null, HousingOrder::getUpdateTime, housingOrderDto.getUpdateTimeEnd());

        wrapper.orderByDesc(BaseEntity::getCreateTime);

        return wrapper;
    }
}
